package com.github.authcloud.server.configure;

import com.github.authcloud.common.AuthConstant;
import com.github.authcloud.server.configure.filter.gateway.GatewayAuthAutoConfigure;
import com.github.authcloud.server.configure.filter.zuul.ZuulAuthAutoConfigure;
import com.github.authcloud.server.configure.properties.AuthCommonProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;


/**
 * @author : zhaoxuan
 * @version : 1.0
 * @date : 2021/8/22 10:51
 * @description : RedisListenerContainerConfigure
 */
@Configuration
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(AuthRedisAutoConfigure.class)
@Import({GatewayAuthAutoConfigure.class, ZuulAuthAutoConfigure.class})
@EnableConfigurationProperties(AuthCommonProperties.class)
public class RedisListenerContainerConfigure {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final AuthCommonProperties authCommonProperties;

    public RedisListenerContainerConfigure(AuthCommonProperties authCommonProperties) {
        this.authCommonProperties = authCommonProperties;
    }

    @Bean
    @DependsOn({"noLoginMappingListenerAdapter", "authMappingListenerAdapter"})
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            @Qualifier("noLoginMappingListenerAdapter") MessageListenerAdapter noLoginMappingListenerAdapter,
                                            @Qualifier("authMappingListenerAdapter") MessageListenerAdapter authMappingListenerAdapter) {
        logger.info("AuthCloud--init redis listener, start listen no login mapping,role and permission mapping info");
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(noLoginMappingListenerAdapter, new PatternTopic(AuthConstant.NO_LOGIN_MAPPING_LISTENER_TOPIC));
        container.addMessageListener(authMappingListenerAdapter, new PatternTopic(AuthConstant.AUTH_MAPPING_LISTENER_TOPIC));
        return container;
    }

    @Bean("noLoginMappingListenerAdapter")
    @ConditionalOnBean(name = "authRedisTemplate")
    @DependsOn("authRedisTemplate")
    MessageListenerAdapter clientRequestMappingListenerAdapter(@Qualifier("authRedisTemplate") RedisTemplate redisTemplate) {
        AuthMappingMessageListener channelMessageListener = new AuthMappingMessageListener(redisTemplate);
        return new MessageListenerAdapter(channelMessageListener, "listenNoLoginMappingEvent");
    }

    @Bean("authMappingListenerAdapter")
    @ConditionalOnBean(name = "authRedisTemplate")
    @DependsOn("authRedisTemplate")
    MessageListenerAdapter userRoleListenerAdapter(@Qualifier("authRedisTemplate") RedisTemplate redisTemplate) {
        AuthMappingMessageListener channelMessageListener = new AuthMappingMessageListener(redisTemplate);
        return new MessageListenerAdapter(channelMessageListener, "listenAuthMappingEvent");
    }

    @Bean
    @ConditionalOnBean(name = "authRedisTemplate")
    @DependsOn("authRedisTemplate")
    AuthMappingCommandLineRunner authMappingCommandLineRunner(@Qualifier("authRedisTemplate") RedisTemplate redisTemplate) {
        return new AuthMappingCommandLineRunner(redisTemplate, authCommonProperties);
    }
}
